package com.cloudcross.ssp.service.impl;

import com.cloudcross.ssp.base.dao.GenericIBatisDao;
import com.cloudcross.ssp.base.web.SimpleController;
import com.cloudcross.ssp.base.web.result.AjaxResult;
import com.cloudcross.ssp.common.Config;
import com.cloudcross.ssp.common.utils.Assert;
import com.cloudcross.ssp.common.utils.MapBuilder;
import com.cloudcross.ssp.common.utils.Pager;
import com.cloudcross.ssp.common.utils.SqlHelper;
import com.cloudcross.ssp.model.Advertiser;
import com.cloudcross.ssp.service.IAdGroupService;
import com.cloudcross.ssp.service.IAdvertiserService;
import com.cloudcross.ssp.service.IBannerService;
import com.cloudcross.ssp.service.IOrderService;
import com.cloudcross.ssp.web.widget.SelectorController.ISelector;
import com.cloudcross.ssp.web.widget.SelectorController.ISelectorProvider;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

@Service
public class AdvertiserService implements IAdvertiserService, ISelectorProvider {

    @Autowired
    private GenericIBatisDao   myBatisDao;
    @Autowired
    private IOrderService      orderService;
    @Autowired
    private IAdGroupService    adGroupService;
    @Autowired
    private IBannerService     bannerService;
    @Autowired
    Config                     config;
    /****************************************************************************/
    //文件系统可上传的文件后缀集合
    private static Set<String> noStuffixSet = new HashSet<String>();

    //初始化可上传文件后缀
    static {
        noStuffixSet.add("jpg");
        noStuffixSet.add("png");
        noStuffixSet.add("pdf");
        noStuffixSet.add("doc");
        noStuffixSet.add("docx");
        noStuffixSet.add("xlsx");
        noStuffixSet.add("xls");
    }

    /****************************************************************************/

    @Override
    public Advertiser findById(Long id) {
        return myBatisDao.get("advertiserSqlMapper.selectById", id);
    }

    @Override
    public long findByName(String name) {
        return myBatisDao.get("advertiserSqlMapper.selectByName", name);
    }

    @Override
    public int countByParams(Map<String, Object> paramMap) {
        return myBatisDao.get("advertiserSqlMapper.countByParams", paramMap);
    }

    @Override
    public int countByParamsOperator(Map<String, Object> paramMap) {
        String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
        paramMap.put("key", paramMap.get("searchKey"));
        paramMap.put("value", searchValue);
        return myBatisDao.get("advertiserSqlMapper.countByParamsoperator", paramMap);
    }

    @Override
    public List<Advertiser> findByParams(Map<String, Object> paramMap, Pager pager) {
        if (pager == null) {
            return myBatisDao.getList("advertiserSqlMapper.selectByParamsExport", paramMap);
        } else {
            paramMap.put("pager", pager);
            return myBatisDao.getList("advertiserSqlMapper.selectByParams", paramMap);
        }
    }

    @Override
    public List<Advertiser> findByParamsBack(Map<String, Object> paramMap, Pager pager) {
        String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
        paramMap.put("key", paramMap.get("searchKey"));
        paramMap.put("value", searchValue);
        paramMap.put("pager", pager);
        return myBatisDao.getList("advertiserSqlMapper.selectByParamsback", paramMap);
    }

    @Override
    public List<Advertiser> findByParamsOperator(Map<String, Object> paramMap, Pager pager) {
        String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
        paramMap.put("key", paramMap.get("searchKey"));
        paramMap.put("value", searchValue);
        paramMap.put("pager", pager);
        return myBatisDao.getList("advertiserSqlMapper.selectByParamsoperator", paramMap);
    }

    public List<Advertiser> findByOperator(Long operatorId) {
        //通过  操作人的 Id 来查找其对应的广告主
        return myBatisDao.getList("selectByOperatoradvertiser", operatorId);
    }

    @Override
    public List<Advertiser> findByOperatorOperator(Long operatorId) {
        //通过  操作人的 Id 来查找其对应的广告主
        return myBatisDao.getList("advertiserSqlMapper.selectByOperatoroperator", operatorId);
    }

    @Override
    public boolean add(Advertiser t) {
        t.setUpdated(new Date());
        t.setAdminId(0L);//和权限相关，保存代理商给广告主分配的账号ID，添加时默认为0L
        myBatisDao.save("advertiserSqlMapper.addAdvertiser", t);
        return true;
    }

    @Override
    public boolean addBack(Advertiser t) {
        //————————————————————————————这个地方要注意一点，operator_id并没有插进去！后面需要做完善的！——————————————————————————————————————————
        t.setUpdated(new Date());
        myBatisDao.save("advertiserSqlMapper.addAdvertiserback", t);
        return true;
    }

    @Override
    public boolean editOperator(Advertiser t) {
        t.setUpdated(new Date());
        myBatisDao.save("advertiserSqlMapper.addAdvertiseroperator", t);
        return true;
    }

    @Override
    public boolean edit(Advertiser t) {
        t.setUpdated(new Date());
        myBatisDao.save("advertiserSqlMapper.editAdvertiser", t);
        return true;
    }

    @Override
    public boolean editBack(Advertiser t) {
        t.setUpdated(new Date());
        myBatisDao.save("advertiserSqlMapper.editAdvertiserback", t);
        return true;
    }

    @Override
    public boolean updateStatus(List<Long> advertiserIdList, int status) {
        myBatisDao.save("advertiserSqlMapper.updateAdvertiserStatus",
                MapBuilder.create(HashMap.class).add("advertiserIdList", advertiserIdList)
                        .add("modifyDate", new Date()).add("status", status).map());
        return true;
    }

    @Override
    public boolean updateSupdated(List<Long> advertiserIdList, int status) {
        myBatisDao.save("advertiserSqlMapper.updateSupdated",
                MapBuilder.create(HashMap.class).add("advertiserIdList", advertiserIdList)
                        .add("modifyDate", new Date()).add("status", status).map());
        return true;
    }

    @Override
    public int countByStatus(Map<String, Object> paramMap) {
        String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
        paramMap.put("key", paramMap.get("searchKey"));
        paramMap.put("value", searchValue);
        return myBatisDao.get("advertiserSqlMapper.countByStatus", paramMap);
    }

    @Override
    public List<Advertiser> findByStatus(Map<String, Object> paramMap) {
        String searchValue = SqlHelper.doLike(paramMap.get("searchValue"));
        paramMap.put("key", paramMap.get("searchKey"));
        paramMap.put("value", searchValue);
        return myBatisDao.getList("advertiserSqlMapper.selectByStatus", paramMap);
    }

    @Override
    public List<Advertiser> findDeliverEffectAnalysis(Map<String, Object> paramMap) {
        return myBatisDao.getList("advertiserSqlMapper.findDeliverEffectAnalysis", paramMap);
    }

    /****************************************************************************/
    @Override
    public @ResponseBody AjaxResult fileUpload(HttpServletRequest request, HttpServletResponse response) {
        AjaxResult result = new AjaxResult();

        try {
            // 创建一个通用的多部分解析器
            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession()
                    .getServletContext());
            // 判断 request 是否有文件上传,即多部分请求
            if (multipartResolver.isMultipart(request)) {
                // 转换成多部分request
                MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
                // 取得request中的所有文件名
                Iterator<String> iter = multiRequest.getFileNames();
                // 取得上传文件
                MultipartFile file = multiRequest.getFile(iter.next());

                if (file != null && file.getSize() >= 0) {
                    if (file.getSize() > 32505856) {
                        result.setStatus(SimpleController.ERROR);
                        result.setMsg("上传文件过大!");
                        return result;
                    }
                    // 取得当前上传文件的文件名称
                    String myFileName = file.getOriginalFilename();
                    // 获取文件后缀
                    String filetype = myFileName.substring(myFileName.lastIndexOf(".") + 1);
                    // 如果所属后缀为不可上传后缀，则返回
                    if (!noStuffixSet.contains(filetype.trim().toLowerCase())) {
                        result.setStatus(SimpleController.ERROR);
                        result.setMsg("文件类型不支持!");
                        return result;
                    }
                    String fileId = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
                    String folder = getFilePath(request);
                    String path = folder + File.separator + fileId + "." + filetype;
                    String smallName = fileId + "_small" + "." + filetype;
                    String smallPath = folder + File.separator + smallName;
                    File distFile = new File(path);
                    if (!distFile.getParentFile().exists()) {
                        distFile.getParentFile().mkdirs();
                    }

                    file.transferTo(distFile);
                    smallPicture(distFile, smallPath, smallName);
                    String str = path.substring(path.indexOf("upload") - 1) + ","
                            + smallPath.substring(path.indexOf("upload") - 1);
                    result.setStatus(SimpleController.OK);
                    result.addData("url", str);
                } else {
                    result.setStatus(SimpleController.ERROR);
                    result.setMsg("上传文件不能为空!");
                    return result;
                }
            }
        } catch (Exception e) {
            result.setStatus(SimpleController.ERROR);
            result.setMsg("上传文件出现异常!");
            return result;
        }
        return result;
    }

    //生成缩略图
    public void smallPicture(File sourceFile, String pathSmall, String uploadName) throws IOException {
        //新建缩略图文件
        File smallFile = new File(pathSmall);
        if (!smallFile.getParentFile().exists()) {
            smallFile.getParentFile().mkdirs();
        }
        //构造image图片
        Image src = javax.imageio.ImageIO.read(sourceFile);
        //表示该图像具有打包成整数的像素的8 位RGB颜色分量
        BufferedImage tag = new BufferedImage(150, 60, BufferedImage.TYPE_INT_BGR);
        //h绘制缩小后的图片
        tag.getGraphics().drawImage(src, 0, 0, 150, 60, null);
        //生成缩略图
        ImageIO.write(tag, "jpg", smallFile);
    }

    private String getFilePath(HttpServletRequest request) {
        // 获取当前上传的年月日
        Calendar cal = Calendar.getInstance();
        // 当前年
        int year = cal.get(Calendar.YEAR);
        // 当前月
        int month = cal.get(Calendar.MONTH) + 1;
        // 当前日
        int day = cal.get(Calendar.DATE);
        //获取文件上传目录
        //获取项目目录
        String realPath = request.getSession().getServletContext().getRealPath("/");
        //获取项目的同级目录
        String root = new File(realPath).getParentFile().getAbsolutePath();
        //到配置文件中获取文件存放的目录
        String upload = config.getResourceUploadDir();
        String path = root + File.separator + upload + File.separator + "advertiser" + File.separator + year
                + File.separator + month + File.separator + day;
        return path;
    }

    @Override
    public String selectAdvertiserNameById(Long id) {
        return myBatisDao.get("advertiserSqlMapper.selectAdvertiserNameById", id);
    }

    /**
     * 创建人：wuqiang.du 创建时间：2015.10.19 16.35 修改广告主的状态，更新他的所有创意，投放的supdate位系统当前时间
     */
    @Override
    public boolean updateSupdatedAll(List<Long> advertiserIdList, Date date) {
        List<Long> list = new ArrayList<Long>();
        //更新广告主的所有投放的supdate
        for (Long l : advertiserIdList) {
            list.addAll(adGroupService.findAllAdGroudByAdvertiserId(l));
        }

        Boolean bannerFlag = false;
        if (list.size() > 0) {
            bannerFlag = this.bannerService.updateSupdated(list, date);
        } else {
            bannerFlag = true;
        }

        return bannerFlag;
    }

    @Override
    public boolean updateStatusAll(List<Long> advertiserIdList, int status) {
        List<Long> list = new ArrayList<Long>();
        Boolean advertiserFlag = updateStatus(advertiserIdList, status);
        Boolean orderFlag = this.orderService.updateStatusByAdvertiserId(advertiserIdList, status);
        Boolean adGroupFlag = this.adGroupService.updateStatusByAdvertiserId(advertiserIdList, status);
        for (Long l : advertiserIdList) {
            list.addAll(adGroupService.findAllAdGroudByAdvertiserId(l));
        }
        Boolean bannerFlag = false;
        if (list.size() > 0) {
            bannerFlag = this.bannerService.updateStatusByAdGroupId(list, status);
        } else {
            bannerFlag = true;
        }
        return advertiserFlag && orderFlag &&  adGroupFlag && bannerFlag;
    }

    //下拉框
    @Override
    public Map<String, List<? extends ISelector>> provideData(String[] parentId) {
        Assert.isTrue(ArrayUtils.isNotEmpty(parentId));
        String operaterId = parentId[0];
        List<Advertiser> advertiserList = findByAgentId(Long.parseLong(operaterId));
        return MapBuilder.create(HashMap.class).add("advertiserList", advertiserList).map();
    }

    @Override
    public List<Advertiser> findByAgentId(Long id) {
        if (id == 0) {
            return myBatisDao.getList("advertiserSqlMapper.selectAllAvertiserId", 0);
        } else {
            return myBatisDao.getList("advertiserSqlMapper.selectByAgentId", id);
        }

    }

    //根据广告主ID更新admin_id
    @Override
    public boolean updateAdvertiserAdminId(Advertiser advertiser) {
        myBatisDao.save("advertiserSqlMapper.updateAdvertiserAdminId", advertiser);
        return true;
    }
}
